using Net;
using System.Collections.Generic;
using System.IO;

public enum MyEnumTest
{
    ENUM_TEST1 = 0,
    ENUM_TEST2 = 1,
    ENUM_TEST3 = 2,
}

/// <summary>
/// // id = 1000, desc = "注册", custom = 1
/// </summary>
public class U2LS_RegisterProto : BaseMessage
{
    public override short MsgId => MessageDefine.U2LS_RegisterProto;
    public ulong Id;
    private readonly uint tag_Id = ProtoHelper.CalcTag(1, "uint64");
    public string Name;
    private readonly uint tag_Name = ProtoHelper.CalcTag(2, "string");
    public string Pass;
    private readonly uint tag_Pass = ProtoHelper.CalcTag(3, "string");

    public override void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Id);
        if (tag_Id == tag_read_Id)
        {
            offset = newOffset;
            Id = ProtoHelper.ReadUInt64(data, ref offset);
        }

        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Name);
        if (tag_Name == tag_read_Name)
        {
            offset = newOffset;
            Name = ProtoHelper.ReadString(data, ref offset);
        }

        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Pass);
        if (tag_Pass == tag_read_Pass)
        {
            offset = newOffset;
            Pass = ProtoHelper.ReadString(data, ref offset);
        }

    }

    public override byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        __bytes = ProtoHelper.WriteUInt64(Id);
        {
            bw.Write(ProtoHelper.WriteTag(1, "uint64"));
            bw.Write(__bytes);
        }

        __bytes = ProtoHelper.WriteString(Name);
        if (__bytes != null && __bytes.Length > 0)
        {
            bw.Write(ProtoHelper.WriteTag(2, "string"));
            bw.Write(__bytes);
        }

        __bytes = ProtoHelper.WriteString(Pass);
        if (__bytes != null && __bytes.Length > 0)
        {
            bw.Write(ProtoHelper.WriteTag(3, "string"));
            bw.Write(__bytes);
        }

        return ms.ToArray();
    }
}

/// <summary>
/// // id = 1001 desc = "注册，登录响应"
/// </summary>
public class LS2U_Response : BaseMessage
{
    public override short MsgId => MessageDefine.LS2U_Response;
    public int[] Code;// 0成功，1失败
    private readonly uint tag_Code = ProtoHelper.CalcTag(1, "int32");
    public string Msg;// 消息
    private readonly uint tag_Msg = ProtoHelper.CalcTag(2, "string");

    public override void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Code);
        if (tag_Code == tag_read_Code)
        {
            offset = newOffset;
            int tag_Code_elem, tag__Code_elem = 0;
            int offsetBeforeReadTag_Code = offset;
            ProtoHelper.ReadTag(data, ref offset, out tag_Code_elem, out int _);
            List<int> list_Code = new List<int>();
            do
            {
                int byte_len_Code = ProtoHelper.ReadLength(data, ref offset);
                int end_Code = offset + byte_len_Code;
                while ( offset < end_Code )
                {
                    list_Code.Add(ProtoHelper.ReadInt32(data, ref offset));
                }
                if (offset >= data.Length) break;
                offsetBeforeReadTag_Code = offset;
                ProtoHelper.ReadTag(data, ref offset, out tag__Code_elem, out int _);
            } while (tag_Code_elem == tag__Code_elem);
            if(offset < data.Length) offset = offsetBeforeReadTag_Code; 
            Code = list_Code.ToArray();
        }

        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Msg);
        if (tag_Msg == tag_read_Msg)
        {
            offset = newOffset;
            Msg = ProtoHelper.ReadString(data, ref offset);
        }

    }

    public override byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        using MemoryStream ms_Code = new MemoryStream();
        using BinaryWriter bw_Code = new BinaryWriter(ms_Code);
        foreach (var item in Code)
        {
            ms_Code.SetLength(0);
            ms_Code.Seek(0, SeekOrigin.Begin);
            __bytes = ProtoHelper.WriteInt32(item);
            {
                bw_Code.Write(__bytes);
            }
            var bytes_Code = ms_Code.ToArray();
            if (bytes_Code.Length > 0)
            {
                bw.Write(ProtoHelper.WriteTag(1, WireType.LengthDelimited));
                bw.Write(ProtoHelper.WriteInt32(bytes_Code.Length));
                bw.Write(bytes_Code);
            }
        }

        __bytes = ProtoHelper.WriteString(Msg);
        if (__bytes != null && __bytes.Length > 0)
        {
            bw.Write(ProtoHelper.WriteTag(2, "string"));
            bw.Write(__bytes);
        }

        return ms.ToArray();
    }
}

/// <summary>
/// // id = 1002
/// </summary>
public class GS2U_BroadCastData : BaseMessage
{
    public override short MsgId => MessageDefine.GS2U_BroadCastData;
    public string Data;
    private readonly uint tag_Data = ProtoHelper.CalcTag(1, "string");

    public override void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Data);
        if (tag_Data == tag_read_Data)
        {
            offset = newOffset;
            Data = ProtoHelper.ReadString(data, ref offset);
        }

    }

    public override byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        __bytes = ProtoHelper.WriteString(Data);
        if (__bytes != null && __bytes.Length > 0)
        {
            bw.Write(ProtoHelper.WriteTag(1, "string"));
            bw.Write(__bytes);
        }

        return ms.ToArray();
    }
}

/// <summary>
/// // id = 1003
/// </summary>
public class U2LS_Login : BaseMessage
{
    public override short MsgId => MessageDefine.U2LS_Login;
    public ulong Id;// id 用户id
    private readonly uint tag_Id = ProtoHelper.CalcTag(1, "uint64");
    public string Name;// 用户名
    private readonly uint tag_Name = ProtoHelper.CalcTag(2, "string");
    public string Pass;// 密码
    private readonly uint tag_Pass = ProtoHelper.CalcTag(3, "string");

    public override void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Id);
        if (tag_Id == tag_read_Id)
        {
            offset = newOffset;
            Id = ProtoHelper.ReadUInt64(data, ref offset);
        }

        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Name);
        if (tag_Name == tag_read_Name)
        {
            offset = newOffset;
            Name = ProtoHelper.ReadString(data, ref offset);
        }

        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_Pass);
        if (tag_Pass == tag_read_Pass)
        {
            offset = newOffset;
            Pass = ProtoHelper.ReadString(data, ref offset);
        }

    }

    public override byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        __bytes = ProtoHelper.WriteUInt64(Id);
        {
            bw.Write(ProtoHelper.WriteTag(1, "uint64"));
            bw.Write(__bytes);
        }

        __bytes = ProtoHelper.WriteString(Name);
        if (__bytes != null && __bytes.Length > 0)
        {
            bw.Write(ProtoHelper.WriteTag(2, "string"));
            bw.Write(__bytes);
        }

        __bytes = ProtoHelper.WriteString(Pass);
        if (__bytes != null && __bytes.Length > 0)
        {
            bw.Write(ProtoHelper.WriteTag(3, "string"));
            bw.Write(__bytes);
        }

        return ms.ToArray();
    }
}

/// <summary>
/// // id = 1004
/// </summary>
public class U2GS_TestRepeated : BaseMessage
{
    public override short MsgId => MessageDefine.U2GS_TestRepeated;
    public int[] array;// 数组
    private readonly uint tag_array = ProtoHelper.CalcTag(1, "int32");

    public override void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_array);
        if (tag_array == tag_read_array)
        {
            offset = newOffset;
            int tag_array_elem, tag__array_elem = 0;
            int offsetBeforeReadTag_array = offset;
            ProtoHelper.ReadTag(data, ref offset, out tag_array_elem, out int _);
            List<int> list_array = new List<int>();
            do
            {
                int byte_len_array = ProtoHelper.ReadLength(data, ref offset);
                int end_array = offset + byte_len_array;
                while ( offset < end_array )
                {
                    list_array.Add(ProtoHelper.ReadInt32(data, ref offset));
                }
                if (offset >= data.Length) break;
                offsetBeforeReadTag_array = offset;
                ProtoHelper.ReadTag(data, ref offset, out tag__array_elem, out int _);
            } while (tag_array_elem == tag__array_elem);
            if(offset < data.Length) offset = offsetBeforeReadTag_array; 
            array = list_array.ToArray();
        }

    }

    public override byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        using MemoryStream ms_array = new MemoryStream();
        using BinaryWriter bw_array = new BinaryWriter(ms_array);
        foreach (var item in array)
        {
            ms_array.SetLength(0);
            ms_array.Seek(0, SeekOrigin.Begin);
            __bytes = ProtoHelper.WriteInt32(item);
            {
                bw_array.Write(__bytes);
            }
            var bytes_array = ms_array.ToArray();
            if (bytes_array.Length > 0)
            {
                bw.Write(ProtoHelper.WriteTag(1, WireType.LengthDelimited));
                bw.Write(ProtoHelper.WriteInt32(bytes_array.Length));
                bw.Write(bytes_array);
            }
        }

        return ms.ToArray();
    }
}

public class Person : IMessageSerializer
{
    public string name;
    private readonly uint tag_name = ProtoHelper.CalcTag(1, "string");
    public int age;
    private readonly uint tag_age = ProtoHelper.CalcTag(2, "int32");

    public void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_name);
        if (tag_name == tag_read_name)
        {
            offset = newOffset;
            name = ProtoHelper.ReadString(data, ref offset);
        }

        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_age);
        if (tag_age == tag_read_age)
        {
            offset = newOffset;
            age = ProtoHelper.ReadInt32(data, ref offset);
        }

    }

    public byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        __bytes = ProtoHelper.WriteString(name);
        if (__bytes != null && __bytes.Length > 0)
        {
            bw.Write(ProtoHelper.WriteTag(1, "string"));
            bw.Write(__bytes);
        }

        __bytes = ProtoHelper.WriteInt32(age);
        {
            bw.Write(ProtoHelper.WriteTag(2, "int32"));
            bw.Write(__bytes);
        }

        return ms.ToArray();
    }
}

public class PersonList : IMessageSerializer
{
    public Person[] list;
    private readonly uint tag_list = ProtoHelper.CalcTag(1, WireType.LengthDelimited);

    public void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_list);
        if (tag_list == tag_read_list)
        {
            offset = newOffset;
            int tag_list_elem, tag__list_elem = 0;
            int offsetBeforeReadTag_list = offset;
            ProtoHelper.ReadTag(data, ref offset, out tag_list_elem, out int _);
            List<Person> list_list = new List<Person>();
            do
            {
                int byte_len_list = ProtoHelper.ReadLength(data, ref offset);
                int end_list = offset + byte_len_list;
                while ( offset < end_list )
                {
                    offsetBeforeReadTag_list = offset;
                    ProtoHelper.ReadTag(data, ref offset, out tag_list_elem, out int _);
                    offset = offsetBeforeReadTag_list;
                    Person person = new Person();
                    person.Deserialize(data,ref offset);
                    list_list.Add(person);
                }
                if (offset >= data.Length) break;
                offsetBeforeReadTag_list = offset;
                ProtoHelper.ReadTag(data, ref offset, out tag__list_elem, out int _);
            } while (tag_list_elem == tag__list_elem);
            if(offset < data.Length) offset = offsetBeforeReadTag_list; 
            list = list_list.ToArray();
        }

    }

    public byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        using MemoryStream ms_list = new MemoryStream();
        using BinaryWriter bw_list = new BinaryWriter(ms_list);
        foreach (var item in list)
        {
            ms_list.SetLength(0);
            ms_list.Seek(0, SeekOrigin.Begin);
            if (item == null) continue;
            bw_list.Write(item.Serialize());
            var bytes_list = ms_list.ToArray();
            if (bytes_list.Length > 0)
            {
                bw.Write(ProtoHelper.WriteTag(1, WireType.LengthDelimited));
                bw.Write(ProtoHelper.WriteInt32(bytes_list.Length));
                bw.Write(bytes_list);
            }
        }

        return ms.ToArray();
    }
}

public class MyEnumMessage : IMessageSerializer
{
    public MyEnumTest enum_test;
    private readonly uint tag_enum_test = ProtoHelper.CalcTag(1, WireType.Varint);

    public void Deserialize(byte[] data,ref int offset)
    {
        int newOffset = offset;
        newOffset = ProtoHelper.ReadRawTagInPlace(data, offset, out uint tag_read_enum_test);
        if (tag_enum_test == tag_read_enum_test)
        {
            offset = newOffset;
            enum_test = (MyEnumTest)ProtoHelper.ReadInt32(data, ref offset);
        }

    }

    public byte[] Serialize()
    {
        byte[] __bytes;
        using MemoryStream ms = new MemoryStream();
        using BinaryWriter bw = new BinaryWriter(ms);

        bw.Write(ProtoHelper.WriteTag(1, WireType.Varint));
        bw.Write(ProtoHelper.WriteInt32((int)enum_test));

        return ms.ToArray();
    }
}

